<?php

namespace App\Http\Controllers;

use App\Exceptions\LessonNotDubException;
use App\Exceptions\LessonNotFoundException;
use App\Internals\CourseInternal;
use App\Models\UserCourse;
use App\Models\UserLesson;
use App\Models\UserLessonDub;
use App\Models\UserStatus;
use App\Services\LlsService;
use FoxLib\Services\UrlParamsService;
use Illuminate\Support\Facades\DB;

class DubController extends Controller
{
    /*
     * @api get /study-api/dubs 跟读配音
     * @version 0.0.1
     * @group web
     *
     * @param query int [pageSize] 页数，默认15
     * @param query int [page] 页码，默认1
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function index()
    {
        $this->validate($this->request, [
            "page" => "integer|min:1",
            "pageSize" => "integer|max:100|min:5"
        ]);
        $page = intval($this->request->input("page", 1));
        $pageSize = intval($this->request->input("pageSize", 15));
        $query = UserLesson::ofUserDub($this->userId);
        $total = $query->count();
        $items = [];
        if ($total) {
            $lessonsObj = $query->orderBy('last_dub_time', 'desc')->forPage($page, $pageSize)->get();
            $lessonIds = [];
            /** @var UserLesson $lessonObj */
            foreach ($lessonsObj as $lessonObj) {
                $lessonIds[] = $lessonObj->getLessonId();
            }
            $lessonsInfo = CourseInternal::getLessons($lessonIds);
            foreach ($lessonsObj as $lessonObj) {
                $tmp = [
                    'star' => $lessonObj->getDubStar(),
                    'date' => $lessonObj->getLastDubTime(),
                    'lessonId' => $lessonObj->getLessonId(),
                    'refer' => UrlParamsService::encode(['userId' => $this->userId, 'lessonId' =>$lessonObj->getLessonId()])
                ];
                $items[] = array_merge($tmp, $lessonsInfo[$lessonObj->getLessonId()]);
            }
        }
        return $this->sendSuccessJson(['total'=>$total, 'items'=>$items]);
    }

    /*
     * @api get /study-api/lessons/{lessonId}/dubs 跟读配音
     * @version 0.0.1
     * @group web
     *
     * @param path int lessonId 课时ID
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function show($lessonId)
    {

        /** @var UserLesson $lessonObj */
        $lessonObj = $this->getUserLesson($lessonId);
        if ($lessonObj->getIsDub()) {
            $dubPages = [];
            $pages = CourseInternal::getLessonSection($lessonId, UserLesson::PROGRESS['dub']);
            $lessonInfo = CourseInternal::getLesson($lessonId);
            if ($pages) {
                foreach ($pages as $k => $item) {
                    /** @var UserLessonDub $dubObj */
                    $dubObj = UserLessonDub::ofUserPage($this->userId, $lessonId, $item['pageId'])->first();
                    if ($dubObj) {
                        $item['dubAudio'] = $dubObj->getUri();
                        $item['duration'] = $dubObj->getDuration();
                        $dubPages[] = $item;
                    }
                }
            }
            $userStatusObj = UserStatus::where('user_id', $this->userId)->first();
            $result = [
                'pages' => $dubPages,
                'cover' => $lessonInfo['cover'],
                'name' => $lessonInfo['name'],
                'audio' => $lessonInfo['audio'],
                'star' => $lessonObj->getDubStar(),
                'refer' => UrlParamsService::encode(['userId' => $this->userId, 'lessonId' => $lessonId]),
                'dubCount' => min($userStatusObj->getDubCount(), 1)
            ];
        } else {
            throw new LessonNotDubException();
        }
        return $this->sendSuccessJson($result);
    }

    /*
     * @api post /study-api/lessons/{lessonId}/dubs 保存跟读配音
     * @version 0.0.1
     * @group web
     *
     * @param path int lessonId 课时ID
     * @param body int text 文本
     * @param body int pageId 页面ID
     * @param body int mediaId 音频ID
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function store($lessonId)
    {
        // 用户配音打分：1 先打分，然后更新
        $this->validate($this->request, [
            'mediaId' => 'required|string',
            'text' => 'required|string',
            'pageId' => 'required|integer',
            'duration' => 'required|integer'
        ]);
        $mediaId = $this->request->input('mediaId');
        $pageId = $this->request->input('pageId');
        $text = $this->request->input('text');
        $duration = $this->request->input('duration');
        $result = LlsService::rate($mediaId, $text);
        /** @var UserLessonDub $lessonDubObj */
        $lessonDubObj = UserLessonDub::ofUserPage($this->userId, $lessonId, $pageId)->first();
        if (!$lessonDubObj) {
            $lessonDubObj = new UserLessonDub();
        }
        $star = UserLessonDub::scoreToStar($result['score']);
        try {
            DB::beginTransaction();
            $lessonDubObj->setUserId($this->userId);
            $lessonDubObj->setLessonId($lessonId);
            $lessonDubObj->setPageId($pageId);
            $lessonDubObj->setUri($result['uri']);
            $lessonDubObj->setScore($result['score']);
            $lessonDubObj->setStar($star);
            $lessonDubObj->setDuration($duration);
            $lessonDubObj->save();
            /** @var UserLesson $lessonObj */
            $lessonObj = $this->getUserLesson($lessonId);
            // 非体验课才统计，更新录音数
            if ($lessonObj->getSequence() && !$lessonObj->getIsDub()) {
                /** @var UserStatus $userStatusObj */
                $userStatusObj = UserStatus::where('user_id', $this->userId)->first();
                $userStatusObj->increment('dub_count');
                $userStatusObj->save();

                /** @var UserCourse $userCourseObj */
                $userCourseObj = UserCourse::ofUserCourse($this->userId, $lessonObj->getCourseId())->first();
                $userCourseObj->increment('dub_count');
                $userCourseObj->save();
            }
            $lessonObj->setIsDub(UserLessonDub::IS_TRUE);
            $lessonObj->setLastDubTime($this->nowTimestamp());
            $lessonObj->save();
            DB::commit();
        } catch (\Exception $e) {
            $this->logger->error($e->getMessage());
            DB::rollBack();
        }
        return $this->sendSuccessJson(['star' => $star, 'duration' => $duration]);
    }


    /*
     * @api delete /study-api/lessons/{lessonId}/dubs 删除跟读配音
     * @version 0.0.1
     * @group web
     *
     * @param path int lessonId 课时ID
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function destroy($lessonId)
    {
        /** @var UserLesson $lessonObj */
        $lessonObj = $this->getUserLesson($lessonId);
        $lessonObj->setIsDub(UserLesson::IS_FALSE);
        $lessonObj->save();
        // 非体验课才减
        if ($lessonObj->getSequence()) {
            $userStatusObj = UserStatus::where('user_id', $this->userId)->first();
            $userStatusObj->decrement('dub_count');
            $userStatusObj->save();
        }
        // 清除数据 page
        UserLessonDub::ofUserLesson($this->userId, $lessonId)->forceDelete();
        return $this->sendSuccessJson();
    }

    private function getUserLesson($lessonId)
    {
        /** @var UserLesson $lessonObj */
        $lessonObj = UserLesson::ofUserLesson($this->userId, $lessonId)->first();
        if (!$lessonObj) {
            throw new LessonNotFoundException();
        }
        return $lessonObj;
    }
}
